<?php
class CF_App_Controller_Request
{
	/**
	 * 
	 * @var string
	 */
	protected $_basePath;
	
	/**
	 * 
	 * @var array
	 */
	protected $_paramSources;
	
	/**
	 * 
	 * @var array
	 */
	protected $_urlParam = array();
	
	/**
	 * 
	 * @var array
	 */
	protected $_urlParamIndex = array();
	
	/**
	 * 
	 * @var string
	 */
	protected $_urlParamDelim = '/';
	
	/**
	 * 
	 * @param string $basePath
	 * @param array $urlParamIndex
	 * @return void
	 */
	public function __construct($basePath = null, array $urlParamIndex = array())
	{
		$this->_basePath = $basePath;
		$this->_urlParamIndex = $urlParamIndex;
		
		$this->_paramSources = array($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV);
		
		$this->_partUrl();
	}
	
	/**
	 * 
	 * @param array $paramSource
	 */
	public function addParamSource(array $paramSource)
	{
		$this->_paramSources[] = $paramSource;
		return $this;
	}
	
	/**
	 * @return void
	 */
	protected function _partUrl()
	{
		$uri = $_SERVER['REQUEST_URI'];
		$uri = str_replace($this->_basePath, '', $uri);
		$uri = explode($this->_urlParamDelim, $uri);
		
		$this->_urlParam = $uri;
		foreach($uri as $v){
			$this->_urlParam[$v] = $v;
		}
	}
	
	/**
	 * 
	 * @param string $name
	 * @param int $index
	 * @return CF_App_Controller_Request $this
	 */
	public function setUrlParamIndex($name, $index)
	{
		$this->_urlParamIndex[$name] = $index;
		return $this;
	}
	
	/**
	 * 
	 * @param array $pIndex
	 * @return CF_App_Controller_Request $this
	 */
	public function setUrlParamsIndex(array $pIndex)
	{
		$this->_urlParamIndex = array_merge($this->_urlParamIndex, $pIndex);
		return $this;
	}
	
	/**
	 * 
	 * @param string $name
	 * @return boolean
	 */
	public function has($name)
	{
		if(isset($this->_urlParamIndex[$name])){
			if(isset($this->_urlParam[$this->_urlParamIndex[$name]])) return true;
		}
		
		if(isset($this->_urlParam[$name])) return true;
		
		foreach($this->_paramSources as $item){
			if(isset($item[$name])) return true;
		}
		
		return false;
	}
	
	/**
	 * 
	 * @param string $name
	 * @param mixed $default
	 * @return mixed
	 */
	public function get($name, $default = null)
	{
		if(isset($this->_urlParamIndex[$name])){
			if(isset($this->_urlParam[$this->_urlParamIndex[$name]]))
				return $this->_urlParam[$this->_urlParamIndex[$name]];
		}
		
		if(isset($this->_urlParam[$name]))
			return $this->_urlParam[$name];
		
		foreach($this->_paramSources as $item){
			if(isset($item[$name]))
				return $item[$name];
		}
		
		return $default;
	}
	
	/**
	 * 
	 * @param string $name
	 * @return boolean
	 */
	public function __isset($name)
	{
		return $this->has($name);
	}
	
	/**
	 * 
	 * @param string $name
	 * @return mixed
	 */
	public function __get($name)
	{
		return $this->get($name);
	}
	
	/**
	 * 
	 * @param string|array|args $names
	 */
	public function getCollection($names)
	{
		if(!is_array($names)) $names = func_get_args();
		
		$data = array();
		foreach ($names as $name){
			$data[$name] = $this->get($name);
		}
		
		return $data;
	}
	
	public function getCollectionIf($names)
	{
		if(!is_array($names)) $names = func_get_args();
		
		$data = array();
		foreach ($names as $name){
			$value = $this->get($name);
			if(null === $value) continue;
			$data[$name] = $value;
		}
		
		return $data;
	}
}